package com.wf.it.hpwebplan;

import com.codingapi.txlcn.tc.annotation.LcnTransaction;
import com.codingapi.txlcn.tc.annotation.TxTransaction;
import com.study.it.sms.SmsUtil;
import com.wf.it.common.annotation.Login;
import com.wf.it.common.api.BookService;
import com.wf.it.common.api.DoctorService;
import com.wf.it.common.api.PlanService;
import com.wf.it.common.api.UserService;
import com.wf.it.common.entity.Book;
import com.wf.it.common.entity.Doctor;
import com.wf.it.common.entity.Plan;
import com.wf.it.common.entity.User;
import com.wf.it.common.util.DateUtil;
import com.wf.it.common.vo.Result;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.print.Doc;
import javax.servlet.http.HttpServletRequest;
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.temporal.ChronoUnit;
import java.util.*;

@RestController
public class BookController {
    @Autowired
    private BookService bookService;
    @Autowired
    private UserService userService;
    @Autowired
    private PlanService planService;
    @Autowired
    private DoctorService docService;

/*    @Autowired
    private SmsUtil smsUtil;*/
    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Login
    @PostMapping("/book/cancel")
    @LcnTransaction
    public Result cancel(int bookid,HttpServletRequest req){
        User curUser= (User) req.getAttribute("cur_user");
        String userIdCard=curUser.getIdCard();
        Result<Book> result_book=bookService.findById(bookid);
        //熔断不能操作
        if(result_book.getState()!=200)
            return result_book;
        Book book=result_book.getObj();
        //不是正常状态不能操作
        if(book.getState()!=1)
            return Result.fail("只能对正常预定信息进行操作");
        //判断是否可以取消(日期差）
        if(DateUtil.daydiff(book.getPlan().getWorkDate(),new Date())<1)
            return Result.fail("只能提前1天操作");
        //后续补充
        Result result1= bookService.cancelBook(bookid);
        if(result1.getState()!=200)
            throw new RuntimeException(result1.getMsg());
        Result result2=planService.updateBookCount(book.getPlan().getId(),-1);
        if(result2.getState()!=200)
            throw new RuntimeException(result2.getMsg());
        Result result3=userService.changeBalance(userIdCard,book.getMoney().intValue());
        if(result3.getState()!=200)
            throw new RuntimeException(result3.getMsg());
        //发送短信
        rabbitTemplate.convertAndSend(
                "exchange.direct1"
                ,"sms.routing.key"
                ,String.format("{\"phone\":\"%s\",\"txt\":\"%s\"}"
                        ,curUser.getPhone()
                        ,book.getPlan().getWorkDateString()+"预约信息取消成功! "));
        //smsUtil.sendSms(curUser.getPhone(),book.getPlan().getWorkDateString()+"预约信息取消成功! ");
        return result1;
    }
    @Login
    @GetMapping("/book/mybooks")
    public Result mybooks(HttpServletRequest req){
        User curUser= (User) req.getAttribute("cur_user");
        String userIdCard=curUser.getIdCard();
        Result<List<Book>> result1=bookService.findListByUser(userIdCard);
        if(result1.getState()!=200)
            return result1;
        //所有医生，一次性查询回来
        Set<String> set=new HashSet<>();
        for(Book book:result1.getObj()){
            set.add(book.getPlan().getDocEmpNo());
        }
        String[] empnos=set.toArray(new String[set.size()]);
        Result<Map<String,Doctor>> result2=docService.findByEmpNos(empnos);
        if(result2.getState()==200) {
            Map<String, Doctor> docMap = result2.getObj();
            for (Book book : result1.getObj()) {
                Doctor doc = docMap.get(book.getPlan().getDocEmpNo());
                book.getMap().put("doc", doc);
                book.getMap().put("deptname", doc.getDeptName());
            }
        }
        //去设置是否可以取消
        for(Book book:result1.getObj()){
           book.getMap().put("isShowCancel",book.getState()==1&&DateUtil.daydiff(book.getPlan().getWorkDate(),new Date())>=1);
        }

        //调用微服务获取医生的信息和部门名称(n+1次查询,效率低)
//        for(Book book:result1.getObj()){
//           String empno= book.getPlan().getDocEmpNo();
//           Result<Doctor> result2=docService.findByEmpNo(empno);
//           Doctor doc=result2.getObj();
//           if(doc!=null) {
//               book.getMap().put("doc", doc);
//               book.getMap().put("deptname",doc.getDeptName());
//           }
//           else
//               book.getMap().put("doc_err",result2.getMsg());
//        }
        return result1;

    }

    @Login
    @PostMapping("/book/add")
     public Result bookadd(int planid, HttpServletRequest req){
        User curUser= (User) req.getAttribute("cur_user");
        String userIdCard=curUser.getIdCard();
        Result<Plan> planResult=planService.findById(planid);
        if(planResult.getState()!=200)
            return planResult;
        Plan plan=planResult.getObj();
        if(plan==null)
            return Result.fail("无此排班信息");
        if(plan.getPlanCount()<=plan.getBookCount()) {
            return Result.fail("对不起，号已经挂满!请选择其他排班");
        }
        if(curUser.getBalance()<plan.getFee()) {
            return Result.fail("对不起，您的余额不足");
        }
        return this.bookOrder(plan,curUser);
       /* //扣钱
        Result result1=userService.changeBalance(userIdCard,-1*plan.getFee());
        if(result1.getState()!=200)
            throw new RuntimeException("扣除余额不成功");
        //增加挂号人数
        Result result2= planService.updateBookCount(planid,1);
        if(result2.getState()!=200)
            throw new RuntimeException("增加挂号人数不成功");
        //增加预定记录
        Result result3=bookService.addBook(planid,userIdCard,plan.getFee());
        if(result3.getState()!=200)
            throw new RuntimeException("插入预订失败");
        //发送短信
        rabbitTemplate.convertAndSend(
                "exchange.direct1"
                ,"sms.routing.key"
                ,String.format("{\"phone\":\"%s\",\"txt\":\"%s\"}"
                        ,curUser.getPhone()
                        ,plan.getWorkDateString()+plan.getRoom()+"预约信息成功!请及时就医"));
        //smsUtil.sendSms(curUser.getPhone(),plan.getWorkDateString()+plan.getRoom()+"预约成功! ");
        return result3;*/
    }

    @LcnTransaction
    public Result  bookOrder(Plan plan,User curUser){
        //扣钱
        Result result1=userService.changeBalance(curUser.getIdCard(),-1*plan.getFee());
        if(result1.getState()!=200)
            throw new RuntimeException("扣除余额不成功");
        //增加挂号人数
        Result result2= planService.updateBookCount(plan.getId(),1);
        if(result2.getState()!=200)
            throw new RuntimeException("增加挂号人数不成功");
        //增加预定记录
        Result result3=bookService.addBook(plan.getId(),curUser.getIdCard(),plan.getFee());
        if(result3.getState()!=200)
            throw new RuntimeException("插入预订失败");
        //发送短信
        rabbitTemplate.convertAndSend(
                "exchange.direct1"
                ,"sms.routing.key"
                ,String.format("{\"phone\":\"%s\",\"txt\":\"%s\"}"
                        ,curUser.getPhone()
                        ,plan.getWorkDateString()+plan.getRoom()+"预约信息成功!请及时就医"));
        //smsUtil.sendSms(curUser.getPhone(),plan.getWorkDateString()+plan.getRoom()+"预约成功! ");
        return result3;
    }
}
